<?php

namespace app\api\controller;

use think\Controller;
use think\facade\App;

class Order extends Auth
{

    public function __construct()
    {
        parent::__construct();
    }

    public function paymentTransaction()
    {
        $post = input('post.');

        if (empty($post['ordersn'])) {
            return $this->json([], 2000, '订单号必传');
        }

        $where = [
            'ordersn' => $post['ordersn'],
        ];

        $info = $this->findTable('payment_transaction', ['where' => $where]);

        if (empty($info)) {
            return $this->json([], 2000, '订单不存在，请确认');
        }

        $wechat = new \WeChat\Pay(config('pay.wxpay'));
        $options = [
            'body' => $info['name'] . $info['mobile'],
            'out_trade_no' => $info['ordersn'],
            'total_fee' => $info['amount'],
            'trade_type' => 'APP',
            'notify_url' => \think\facade\Request::baseFile(true) . '/api/notify/wxpaynotify',
            'spbill_create_ip' => get_ip(),
        ];

        try {
            // 生成预支付码
            $result = $wechat->createOrder($options);

            if (empty($result)) {
                return $this->json([], 2000, '支付创建失败');
            }

            if ($result['result_code'] != 'SUCCESS' && isset($result['err_code'])) {
                $msg = empty($result['err_code_des']) ? '支付发起失败' : $result['err_code_des'];
                return $this->json([], 2000, $msg);
            }

            if (empty($result['prepay_id'])) {
                return $this->json([], 2000, '支付发起失败');
            }

            // 创建APP参数签名
            $options = $wechat->createParamsForApp($result['prepay_id']);

            $data = [
                'payamount' => $info['amount'],
                'memberid' => $info['memberid'],
                'orderid' => $info['orderid'],
                'ordersn' => $info['ordersn'],
                'revision' => 0,
                'paymentid' => $options['prepayid'],
                'commodityname' => $options['body'],
            ];

            $ans = $this->insertTable('payment_transaction', $data);
        } catch (\Exception $e) {
        }
    }

    public function applyOrder()
    {

        $orderid = input('post.orderid');
        if (empty($orderid)) {
            return $this->json([], 2000, '抢单参数错误');
        }

        $where = ['orderid' => $orderid];

        $info = $this->findTable('order', ['where' => $where]);

        if (empty($info)) {
            return $this->json([], 2000, '订单不存在，请刷新重试');
        }

        if ($info['status'] > 1) {
            return $this->json([], 2000, '该订单已被接单');
        }

        $data = [
            'orderid' => $info['orderid'],
            'ordersn' => $info['ordersn'],
            'coachid' => $this->userid,
            'coachname' => $this->userInfo['coachname'],
        ];

        $ans = $this->insertTable('apply_order', $data);
        $this->addCustomer(['memberid' => $info['memberid'], 'coachid' => $this->userid, 'source' => 1]);

        if ($ans) {
            return $this->json($ans, 1001);
        } else {
            return $this->json($orderid, 2000, '抢单失败');
        }
    }

    /**
     *
     * @param int $code
     */
    protected function urnRet($return_code = "FAIL", $return_msg = "支付回调失败")
    {
        $xmlTpl = "<xml><return_code><![CDATA[%s]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>";
        $xml = sprintf($xmlTpl, $return_code, $$return_msg);
        return exit($xml);
    }

    /**
     *
     * @return void
     */
    public function notify()
    {
        ini_set('date.timezone', 'Asia/Shanghai');
        error_reporting(E_ERROR);

        $xml = file_get_contents("php://input");
        $xmlTpl = "<xml><return_code><![CDATA[%s]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>";
        if (!$xml) {
            Log::record('[ wxpay_notify_response ] ' . print_r($xml, true), 'debug');
            $result = sprintf($xmlTpl, 'FAIL', 'xml数据异常！');
        }

        //日志记录接收到的数据
        Log::record('[ wxpay_notify_response ] begin \ ' . print_r($xml, true), 'info');

        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $obj = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

        //检验签名是否正确
        if ($this->checkSign($obj) && ($obj['return_code'] == 'SUCCESS') && ($obj['result_code'] == 'SUCCESS')) {
            Log::record('[ wxpay_notify_response ] 回调签名验证成功', 'info');

            //验证成功
            $order = $obj['out_trade_no']; //订单号
            $userid = $obj['attach']; //用户id
            $money = $obj['total_fee']; //金额
            $transaction_id = $obj['transaction_id']; //微信支付订单号

            //检查该订单是否已经处理过，处理过就直接返回微信
            $mkt_clearance_order = $this->commonLogic->findTable($this->tableOrderName, [
                'where' => [
                    ['isdel', 'eq', 0],
                    ['ordersn', 'eq', $order],
                ],
                'order' => 'id desc',
            ]);

            $mkt_clearance = $this->commonLogic->findTable($this->tableName, [
                'where' => [
                    ['id', 'eq', $mkt_clearance_order['clearanceid']],
                ],
                'field' => 'status,type,voucherid',
            ]);

            $status = $mkt_clearance_order['status'];
            if ($status >= 2) {
                //返回微信这个订单已经处理完了，不必重复请求
                $result = sprintf($xmlTpl, 'SUCCESS', 'OK');
                echo $result;
                exit();
            }

            //更新订单状态
            $ans = $this->commonLogic->updateTable($this->tableOrderName, [
                'where' => [
                    ['ordersn', 'eq', $order],
                ],
                'data' => [
                    'tradesn' => $transaction_id,
                    'price' => bcdiv($money, 100, 2),
                    'paynotifytime' => time(),
                    'status' => 2,
                    'paynotifyxml' => print_r($xml, true),
                ],
            ]);

            if ($mkt_clearance['type'] == 2 && $mkt_clearance['voucherid'] > 0) {
                $ans = $this->commonLogic->updateTable($this->tableVoucherName, [
                    'where' => [
                        ['voucherid', 'eq', $mkt_clearance['voucherid']],
                    ],
                    'data' => [
                        'updatetime' => time(),
                        'status' => 3,
                    ],
                ]);
            }

            if ($ans) {
                Log::record('[ wxpay_notify_response ] 订单支付成功', 'info');
                // if ($mkt_clearance['status'] == 5 || $mkt_clearance['type'] == 3) {
                // if ($mkt_clearance['status'] == 5) {
                //     $manDoorPar = $this->manDoorParkByPlateNum([
                //         'money' => bcdiv($money, 100, 2),
                //         'plateNum' => $mkt_clearance_order['plate']
                //     ], $mkt_clearance_order['clearanceid']);
                //     Log::record('[ wxpay_notify_response ] 提交车辆抬杠' . print_r($manDoorPar, true), 'info');
                // } else {
                $paycar = $this->addPayCat([
                    'dld' => $mkt_clearance_order['shopsn'],
                    'paidMoney' => bcdiv($money, 100, 2),
                    'plateNum' => $mkt_clearance_order['plate'],
                    'remark' => '微信支付',
                ], $mkt_clearance_order['clearanceid']);
                Log::record('[ wxpay_notify_response ] 提交放行资料' . print_r($paycar, true), 'info');
                // }
                $result = sprintf($xmlTpl, 'SUCCESS', 'OK');
            } else {
                Log::record('[ wxpay_notify_response ] 订单支付失败, 更新订单状态失败,订单号：' . $order, 'debug');
                $result = sprintf($xmlTpl, 'FAIL', '订单支付失败');
            }
        } else {
            Log::record('[ wxpay_notify_response ] 签名错误' . print_r($xml, true), 'debug');
            $result = sprintf($xmlTpl, 'FAIL', '签名错误');
        }
        echo $result;
        exit();
    }

    //检查回调签名是否正确
    public function checkSign($arr)
    {
        $isNotEmptyArr = array_filter($arr);
        if (isset($isNotEmptyArr['sign'])) {
            unset($isNotEmptyArr['sign']);
        }
        //2.按照字典进行排序
        ksort($isNotEmptyArr);
        //3.组成URL键值对,使用urldecode是为了适应isNotEmptyArr中包含了中文串
        $queryStr = urldecode(http_build_query($isNotEmptyArr));
        //4.和KEY拼接
        $stringSignTemp = $queryStr . "&key=" . config('pay.wxpay.mch_key');
        //对结果进行md5之后,全部转换成大写
        $sign = strtoupper(md5($stringSignTemp));
        //返回签名
        return $sign == $arr['sign'];
    }

    public function addOrder()
    {
        $post = input('post.');
        $builarr = ['trainingcourse' => '培训科目', 'trainingmodel' => '培训车型', 'examinecity' => '考试城市', 'collegename' => '学员姓名', 'collegemobile' => '学员手机', 'collegeage' => '学员年龄', 'collegeaddress' => '地址', 'province' => '省份'];

        $data = [];
        foreach ($builarr as $key => $val) {
            if (empty($post[$key])) {
                return $this->json($post, 2000, '请输入正确' . $val);
            }
            $data[$key] = empty($post[$key]) ? '' : $post[$key];
        }

        if ((int) $data['collegeage'] < 18 || (int) $data['collegeage'] > 70) {
            return $this->json($post, 2000, '驾照最低的年龄要求在18周岁以上，70周岁以下年龄');
        }

        if (!empty($post['collegedetailedaddress'])) {
            return $this->json($post, 2000, '请输入详细地址');
        }
        $data['collegedetailedaddress'] = $post['collegedetailedaddress'];

        if ($this->user['membermobile'] != $data['collegemobile']) {
            return $this->json($post, 2000, '学员手机号码与用户不一致');
        }

        $info = $this->findTable('order', ['where' => [
            ['memberid', '=', $this->userid],
            ['isdel', '=', 0],
            ['status', '<', 5]
        ]]);

        if (!empty($info)) {
            return $this->json($post, 2000, '您已存在未完成的订单，当前订单完成才能继续发单');
        }
        $ordersn = $this->buildSn();

        if (!empty($post['city'])) {
            $data['city'] = $post['city'];
        }

        if (!empty($post['area'])) {
            $data['area'] = $post['area'];
        }

        $data['memberid'] = $this->userid;
        $data['ordersn'] = $ordersn;

        $address = $data['collegeaddress'] . $data['collegedetailedaddress'];
        $result = $this->getgaode($address);
        if ($result['code'] == 1000) {
            if (!empty($result['data'])) {
                $location = $result['data'];
                $data['longitude'] = empty($location[0]) ? '' : $location[0];
                $data['latitude'] = empty($location[1]) ? '' : $location[1];
            }
        } else {
            return $this->json($result['data'], $result['code'], $result['msg']);
        }

        if (!empty($post['longitude']) && !empty($post['latitude'])) {
            $data['longitude'] = $post['longitude'];
            $data['latitude'] = $post['latitude'];
        }

        $ans = $this->insertTable('order', $data);
        if ($ans) {
            return $this->json($ans, 1001, '发单成功');
        } else {
            return $this->json($ans, 2000, '发单失败');
        }
    }
}
